#问题：如何使用魔法方法

'''
最常用的几种魔法方法的使用方法：

__init__构造器，当一个实例被创建的时候初始化的方法；
__new__实例化对象调用的第一个方法，它只取下 cls 参数，并把其他参数传给__init__；
__call__允许一个类的实例像函数一样被调用；
__getitem__定义获取容器中指定元素的行为，相当于 self[key]；
__getattr__定义当用户试图访问一个不存在属性的时候的行为；
__setattr__定义当一个属性被设置的时候的行为；
__getattribute__定义当一个属性被访问的时候的行为。

'''

#在面向对象编程中，如果你想自定义的类中重载某个内置运算符的行为，
# 那么就必须重写相对应的魔法方法。我们写一个最简单的字符类

class String:
    # 初始化
    def __init__(self, string):
        self.string = string

    # 打印对象
    def __repr__(self):
        return 'Object: {}'.format(self.string)

    # 合并其它
    def __add__(self, other):
        return self.string + other
    
    #__call__ 可以使对象被当作函数直接调用
    def __call__(self,*args,**kwargs):
        print ("xxxx",args,kwargs)

# 测试代码
if __name__ == '__main__':
    # 创建对象，相当于调用string1 = String.__init__('Hello')
    string1 = String('Hello')
    # 打印对象, 就相当于调用`string1.__repr__()`。
    print(string1)
    # 连接一个自定义字符对象和一个内置的字符对象
    print(string1 +' world')
    #直接把对象当作函数调用
    string1(123,456, name = "aaa")

#视频讲解：
#https://www.bilibili.com/video/BV1A4411v7b2?p=60
#https://www.bilibili.com/video/BV1V5411s7p4?from=search&seid=3880588812752821565
#官方文档 https://docs.python.org/zh-cn/3/reference/datamodel.html#basic-customization